package server

import (
	"core/corestruct"
	"core/datetime"
	"core/db"
	"core/server/baseserver"
	"iotall/iotcore/entity"

	"github.com/dubbogo/gost/log/logger"
	"gorm.io/gorm/clause"
)

type OnlineServer struct {
	baseserver.BaseServer
	list *corestruct.QueueT[entity.StdPkg]
}

func (p *OnlineServer) Start() {
	p.BaseServer.Name = "设备在线状态"
	p.BaseServer.Interval = 5000
	p.BaseServer.DoInterval = p.DoInterval
	p.BaseServer.DoClose = p.DoInterval

	p.list = &corestruct.QueueT[entity.StdPkg]{}
	p.BaseServer.Start()
}
func (p *OnlineServer) Save() {
	var maxbatch = 2000
	var list = p.list.PopAll(maxbatch)
	if len(list) == 0 {
		return
	}

	var revdata = make([]*entity.CommDevice, 0)
	var offline = make([]*entity.CommDevice, 0)
	for _, v := range list {
		if v.PhysicalState == "离线" {
			var mold = p.FindDevice(offline, v.Sid)
			if mold != nil {
				mold.Id = v.Id //记录大id
				continue
			}
			var m = &entity.CommDevice{
				Id:  v.Id,
				Sid: v.Sid,
			}
			offline = append(offline, m)
		} else {
			var mold = p.FindDevice(revdata, v.Sid)
			if mold != nil {
				mold.Id = v.Id
				continue
			}
			var m = &entity.CommDevice{
				Id:            v.Id,
				Sid:           v.Sid,
				CommPortId:    v.CommPortId,
				CommProxyId:   v.CommProxyId,
				CommDealId:    v.CommDealId,
				ClientId:      v.ClientId,
				PhysicalState: "在线",
				LogicState:    "在线",
				LstRevDt:      nil,
				LogicTimeOut:  0,
			}
			var dt = datetime.Now()
			m.LstRevDt = &dt
			revdata = append(revdata, m)
		}
	}
	//删除离线信息
	for _, v := range revdata {
		var old = p.FindDevice(offline, v.Sid)
		if old != nil {
			old.Sid = "" //离线信息不处理了
			//比较时间
			if old.Id > v.Id {
				v.PhysicalState = "离线"
			}
		}
	} //"logic_state"  不要写入，用专门线程处理
	var fields = []string{"comm_port_id", "comm_proxy_id", "comm_deal_id", "client_id", "physical_state", "lst_rev_dt"}
	tx := db.DbMaster.Clauses(clause.OnConflict{
		Columns:   []clause.Column{{Name: "sid"}},
		DoUpdates: clause.AssignmentColumns(fields),
	}).Create(&revdata)
	logger.Infof("数据库操作 %v", tx)

	if len(offline) > 0 {
		var offsid = make([]string, 0)
		for _, v := range offline {
			if v.Sid != "" {
				offsid = append(offsid, v.Sid)
			}
		}
		if len(offsid) > 0 {
			tx = db.DbMaster.Model(&entity.CommDevice{}).Where("sid in ?", offsid).UpdateColumn("physical_state", "离线")
			logger.Info(tx)
		}
	}

	if maxbatch == len(list) {
		p.Save()
	}
}
func (p *OnlineServer) DoInterval() {
	p.Save()
}
func (p *OnlineServer) FindDevice(arr []*entity.CommDevice, sid string) *entity.CommDevice {
	for _, v := range arr {
		if v.Sid == sid {
			return v
		}
	}
	return nil
}
func (p *OnlineServer) Push(m entity.StdPkg) {
	p.list.Push(m)
}

var OnlineSvr *OnlineServer

func init() {
	OnlineSvr = &OnlineServer{}
	OnlineSvr.Start()
}
